/*
**  Copyright (c) 2014 Michael Liu(michael.liu.point@gmail.com).
**
**  Project: Gateway Unified Management Platform
**  File:    samgr.c
**  Author:  Michael
**  Date:    07/09/2014
**
**  Purpose:
**    system admin management implement.
*/

/* Include files. */

#include "common.h"
#include "dpmgr.h"
#include "eamgr.h"
#include "samgr.h"
#include "svcmgr.h"
#include "osdep.h"
#include "pfdep.h"

/* Macro constant definitions. */

/* Type definitions. */

/* Local function declarations. */

static e_ret sa_sysmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size);
static e_ret sa_cfgmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size);
static e_ret sa_fwmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size);
static e_ret sa_logmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size);

static e_ret sa_add_httpd_svc();
static e_ret httpd_svc_start(tsm_svc * svc);

#ifdef SA_SUPPORT_NBNSD
static e_ret sa_add_nbnsd_svc();
static e_ret nbnsd_svc_start(tsm_svc * svc);
#endif /* SA_SUPPORT_NBNSD */
extern e_ret http_redirect_start(void);
extern e_ret http_redirect_stop(void);

/* Macro API definitions. */

/* Global variable declarations. */

tsys_admin *system_admin;

e_ret sys_admin_init(tsys_admin * sa)
{

	struct list_head *each;
	tsa_dev *sa_dev;

	sysmgr_trace_enter();

	system_admin = sa;

	list_for_each(each, &sa->all_devs) {
		sa_dev = list_entry(each, tsa_dev, list);
		if (sa_dev->opt != NULL) {
			sa_dev->opt(sa_dev, eSA_DEV_OPT_INIT, NULL);
		}
	}

	sysmgr_trace_exit();
	return (eRET_SUCCESS);

}

e_ret sys_admin_start(void)
{

	tsa_dev *led;
	tsa_dev *sa_dev;
	unsigned char qis_done;
	struct list_head *each;
	tled_opt_cfg led_opt;

	sysmgr_trace_enter();

	run_ntpclient_update_time(system_admin->ntp_server);

	/* Start HTTPD server. */
	sa_add_httpd_svc();

#ifdef SA_SUPPORT_NBNSD
	/* Start Netbios server. */
	sa_add_nbnsd_svc();
#endif /* SA_SUPPORT_NBNSD */

	pf_dep_get_qis(&qis_done);
	if (!qis_done) {
		http_redirect_start();
	}

	/* Apply Power Save Config */
	led = NULL;
	list_for_each(each, &system_admin->all_devs) {
		sa_dev = list_entry(each, tsa_dev, list);
		if (strstr(sa_dev->name, "led") != NULL) {
			led = sa_dev;
			break;
		}
	}

	if (led == NULL) {
		sysmgr_err("LED device NOT found in system admin device list.\n");
		return (eRET_INVALID_STATE);
	}

	memset(&led_opt, 0, sizeof(led_opt));
	if (led->opt != NULL) {
		led->opt(led, eLED_OPT_GET_POWER_SAVE, &led_opt);
		led->opt(led, eLED_OPT_SET_POWER_SAVE, &led_opt);
	}

	sysmgr_trace_exit();
	return (eRET_SUCCESS);

}

e_ret sa_add_httpd_svc()
{
	tsm_svc *svc;

	sysmgr_trace_enter();

	svc = malloc(sizeof(tsm_svc));
	if (svc == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", (sizeof(tsm_svc)), errno, strerror(errno));
		sysmgr_trace_exit();
		return (eRET_NO_RESOURCE);
	}
	memset(svc, 0, sizeof(tsm_svc));
	os_dep_mutex_init(&svc->mutex);
	strcpy(svc->name, SYSMGR_SVC_HTTPD);
	svc->enable = eBOOL_TRUE;
	svc->start = httpd_svc_start;

	httpd_svc_start(svc);

	svcmgr_add_svc(svc);

	sysmgr_trace_exit();

	return (eRET_SUCCESS);

}

e_ret httpd_svc_start(tsm_svc * svc)
{
	int rc;

	sysmgr_trace_enter();

	os_dep_mutex_lock(&svc->mutex);
	svc->task = 0;

	os_dep_killall("httpd", "-SIGTERM");
	usleep(1000);
	/*
	 **  NOW: SVC -> task == 0,
	 **  So we can direct send Child signal to make sure process has been Reclaim.
	 **  It's a double check.
	 */
	os_dep_killall("sysmgr", "-SIGCHLD");
	usleep(1000);

	rc = os_dep_do_system_raw(eBOOL_FALSE, &svc->task, "httpd", "-f", "-h", "/etc_ro/www", NULL);
	sysmgr_dbg("os_dep_do_system_raw(httpd), rc: %d\n", rc);

	os_dep_mutex_unlock(&svc->mutex);
	sysmgr_trace_exit();

	return (eRET_SUCCESS);
}

#ifdef SA_SUPPORT_NBNSD
e_ret sa_add_nbnsd_svc()
{
	tsm_svc *svc;

	sysmgr_trace_enter();

	svc = malloc(sizeof(tsm_svc));
	if (svc == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", (sizeof(tsm_svc)), errno, strerror(errno));
		sysmgr_trace_exit();
		return (eRET_NO_RESOURCE);
	}
	memset(svc, 0, sizeof(tsm_svc));
	os_dep_mutex_init(&svc->mutex);
	strcpy(svc->name, SYSMGR_SVC_NBNSD);
	svc->enable = eBOOL_TRUE;
	svc->start = nbnsd_svc_start;

	nbnsd_svc_start(svc);

	svcmgr_add_svc(svc);

	sysmgr_trace_exit();

	return (eRET_SUCCESS);

}

e_ret nbnsd_svc_start(tsm_svc * svc)
{
	int rc;

	sysmgr_trace_enter();

	os_dep_mutex_lock(&svc->mutex);
	svc->task = 0;

	os_dep_killall("nbnsd", "-SIGTERM");
	usleep(1000);
	/*
	 **  NOW: SVC -> task == 0,
	 **  So we can direct send Child signal to make sure process has been Reclaim.
	 **  It's a double check.
	 */
	os_dep_killall("sysmgr", "-SIGCHLD");
	usleep(1000);

	rc = os_dep_do_system_raw(eBOOL_FALSE, &svc->task, "nbnsd", "-f", "-n", PF_DEP_MANAGEMENT_URL, "-i", "lan",
				  NULL);
	sysmgr_dbg("os_dep_do_system_raw(nbnsd), rc: %d\n", rc);

	os_dep_mutex_unlock(&svc->mutex);
	sysmgr_trace_exit();

	return (eRET_SUCCESS);
}
#endif /* SA_SUPPORT_NBNSD */

e_ret sys_admin_proc_req(tcm_req_body * req, tcm_rsp_body ** rsp)
{
	e_ret ret = eRET_SUCCESS;
	int size = 0;
	tcm_sa_req_body *sa_req;
	tcm_sa_rsp_body *sa_rsp = NULL;
	tcm_rsp_body *new_rsp = NULL;

	sysmgr_trace_enter();

	sa_req = (tcm_sa_req_body *) req->mod_req_body;
	switch (sa_req->submod) {
	case eSA_SUB_MOD_SYS_MGR:
		ret = sa_sysmgr_proc_req(system_admin, sa_req, &sa_rsp, &size);
		break;

	case eSA_SUB_MOD_CFG_MGR:
		ret = sa_cfgmgr_proc_req(system_admin, sa_req, &sa_rsp, &size);
		break;

	case eSA_SUB_MOD_FW_MGR:
		ret = sa_fwmgr_proc_req(system_admin, sa_req, &sa_rsp, &size);
		break;

	case eSA_SUB_MOD_LOG_MGR:
		ret = sa_logmgr_proc_req(system_admin, sa_req, &sa_rsp, &size);
		break;

	default:
		ret = eRET_INVALID_ARG;
		break;
	}

	if (sa_rsp != NULL) {
		sa_rsp->submod = sa_req->submod;
		new_rsp = malloc(sizeof(*new_rsp) + size);
		if (new_rsp == NULL) {
			sysmgr_err("malloc(%d) failed, err: %d,[%s]\n",
				   (sizeof(*new_rsp) + size), errno, strerror(errno));
			ret = eRET_NO_RESOURCE;
			goto out;
		} else {
			new_rsp->ret = ret;
			new_rsp->rsp_body_len = size;
			memcpy(new_rsp->mod_rsp_body, sa_rsp, size);
			*rsp = new_rsp;
		}
		free(sa_rsp);
	}

out:
	*rsp = new_rsp;

	sysmgr_trace_exit();
	return (ret);
}

e_ret sa_sysmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size)
{

	e_ret ret = eRET_SUCCESS;
	int rsp_size;
	tcm_sa_rsp_body *new_rsp;
	tcm_sa_sm_req_body *sm_req;
	tcm_sa_sm_rsp_body *sm_rsp;
	tcm_sa_sm_rsp_body sm_rsp_body;
	static tsa_dev *led;
	tled_opt_cfg led_opt;

	sysmgr_trace_enter();

	rsp_size = 0;
	new_rsp = NULL;

	sm_req = (tcm_sa_sm_req_body *) req->body;
	memset(&sm_rsp_body, 0, sizeof(sm_rsp_body));

	switch (sm_req->opt) {
	case eSYS_MGR_OPT_VERIFY_PASSWORD:
		ret = pf_dep_check_password(sm_req->pswd.password, &sm_rsp_body.pswd.verify_ok);
		sysmgr_dbg("pf_dep_check_password(%s) ok[%d], ret: %d\n",
			   sm_req->pswd.password, sm_rsp_body.pswd.verify_ok, ret);
		break;

	case eSYS_MGR_OPT_SET_PASSWORD:
		ret = pf_dep_set_password(sm_req->pswd.password);
		sysmgr_dbg("pf_dep_set_password(%s), ret: %d\n", sm_req->pswd.password, ret);
		break;

	case eSYS_MGR_OPT_GET_PASSWORD:
		ret = pf_dep_get_password(sm_rsp_body.pswd.password);
		sysmgr_dbg("pf_dep_get_password(%s), ret: %d\n", sm_rsp_body.pswd.password, ret);
		break;

	case eSYS_MGR_OPT_SET_QIS:
		if (sm_req->qis.qis_done) {
			/* Stop HTTP Redirect */
			http_redirect_stop();
		}
		ret = pf_dep_set_qis(sm_req->qis.qis_done);
		sysmgr_dbg("pf_dep_set_qis(%d), ret: %d\n", sm_req->qis.qis_done, ret);
		break;

	case eSYS_MGR_OPT_GET_QIS:
		ret = pf_dep_get_qis(&sm_rsp_body.qis.qis_done);
		sysmgr_dbg("pf_dep_get_qis() qis_done[%d], ret: %d\n", sm_rsp_body.qis.qis_done, ret);
		break;

	case eSYS_MGR_OPT_GET_UPTIME:
		ret = os_dep_get_uptime(&sm_rsp_body.uptime);
		sysmgr_dbg("pf_dep_get_uptime() uptime day[%u] hours[%u] min[%u] second[%u], ret: %d\n",
			   sm_rsp_body.uptime.day, sm_rsp_body.uptime.hour, sm_rsp_body.uptime.minute,
			   sm_rsp_body.uptime.second, ret);

		break;

	case eSYS_MGR_OPT_GET_DATETIME:
		ret = os_dep_get_datetime(&sm_rsp_body.datetime.datetime);
		if (ret != eRET_SUCCESS) {
			sysmgr_err("os_dep_get_datetime() failed, ret: %d\n", ret);
			break;
		}
		sysmgr_dbg("pf_dep_get_datetime() datetime day[%u] hours[%u] min[%u] second[%u], ret: %d\n",
			   sm_rsp_body.datetime.datetime.day, sm_rsp_body.datetime.datetime.hour,
			   sm_rsp_body.datetime.datetime.minute, sm_rsp_body.datetime.datetime.second, ret);

		ret = pf_dep_get_ntp(sm_rsp_body.datetime.ntp_server);
		if (sm_rsp_body.datetime.ntp_server[0] != 0) {
			sm_rsp_body.datetime.use_ntp = eBOOL_TRUE;
		}
		sysmgr_dbg("pf_dep_get_ntp() ntpserver[%s], ret: %d\n", sm_rsp_body.datetime.ntp_server, ret);
		break;

	case eSYS_MGR_OPT_SET_DATETIME:
		if (sm_req->datetime.use_ntp) {
			ret = pf_dep_set_ntp(sm_req->datetime.ntp_server);
			sysmgr_dbg("pf_dep_set_ntp() ntpserver[%s], ret: %d\n", sm_req->datetime.ntp_server, ret);
		} else {
			ret = os_dep_set_datetime(&sm_req->datetime.datetime);
			sysmgr_dbg("pf_dep_set_datetime() datetime day[%u] hours[%u] min[%u] second[%u], ret: %d\n",
				   sm_rsp_body.datetime.datetime.day, sm_rsp_body.datetime.datetime.hour,
				   sm_rsp_body.datetime.datetime.minute, sm_rsp_body.datetime.datetime.second, ret);
		}
		break;

	case eSYS_MGR_OPT_GET_TIMEZONE:
		ret = pf_dep_get_timezone(&sm_rsp_body.datetime.tz);
		sysmgr_dbg("pf_dep_get_timezone() timezone[%u], ret: %d\n", sm_rsp_body.datetime.tz, ret);
		break;

	case eSYS_MGR_OPT_SET_TIMEZONE:
		ret = pf_dep_set_timezone(sm_req->datetime.tz);
		sysmgr_dbg("pf_dep_set_timezone() timezone[%u], ret: %d\n", sm_req->datetime.tz, ret);
		break;

	case eSYS_MGR_OPT_GET_LANGUAGE:
		ret = pf_dep_get_language(&sm_rsp_body.lang);
		sysmgr_dbg("pf_dep_get_language() language[%u], ret: %d\n", sm_rsp_body.lang, ret);
		break;

	case eSYS_MGR_OPT_SET_LANGUAGE:
		ret = pf_dep_set_language(sm_req->lang);
		sysmgr_dbg("pf_dep_set_language() language[%u], ret: %d\n", sm_req->lang, ret);
		break;

	case eSYS_MGR_OPT_GET_POWER_SAVE:
		if (led == NULL) {
			tsa_dev *sa_dev;
			struct list_head *each;

			list_for_each(each, &system_admin->all_devs) {
				sa_dev = list_entry(each, tsa_dev, list);
				if (strstr(sa_dev->name, "led") != NULL) {
					led = sa_dev;
					break;
				}
			}
			if (led == NULL) {
				sysmgr_err("LED device NOT found in system admin device list.\n");
				return (eRET_INVALID_STATE);
			}
		}

		memset(&led_opt, 0, sizeof(led_opt));
		if (led->opt != NULL) {
			ret = led->opt(led, eLED_OPT_GET_POWER_SAVE, &led_opt);
		} else {
			sysmgr_err("LED device do NOT have operation method.\n");
			ret = eRET_INVALID_STATE;
		}
		sm_rsp_body.power_save = led_opt.power_save;
		sysmgr_dbg("get power save[%u], ret: %d\n", sm_rsp_body.power_save, ret);
		break;

	case eSYS_MGR_OPT_SET_POWER_SAVE:
		if (led == NULL) {
			tsa_dev *sa_dev;
			struct list_head *each;

			list_for_each(each, &system_admin->all_devs) {
				sa_dev = list_entry(each, tsa_dev, list);
				if (strstr(sa_dev->name, "led") != NULL) {
					led = sa_dev;
					break;
				}
			}
			if (led == NULL) {
				sysmgr_err("LED device NOT found in system admin device list.\n");
				return (eRET_INVALID_STATE);
			}
		}

		memset(&led_opt, 0, sizeof(led_opt));
		led_opt.power_save = sm_req->power_save;
		if (led->opt != NULL) {
			ret = led->opt(led, eLED_OPT_SET_POWER_SAVE, &led_opt);
		} else {
			sysmgr_err("LED device do NOT have operation method.\n");
			ret = eRET_INVALID_STATE;
		}
		sysmgr_dbg("set power save[%u], ret: %d\n", sm_req->power_save, ret);
		break;

	case eSYS_MGR_OPT_REBOOT:
		ret = pf_dep_reboot();
		sysmgr_dbg("pf_dep_reboot() ret: %d\n", ret);
		break;

	default:
		ret = eRET_INVALID_ARG;
		break;
	}

	rsp_size = sizeof(*new_rsp) + sizeof(*sm_rsp);
	new_rsp = malloc(rsp_size);
	if (new_rsp == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", rsp_size, errno, strerror(errno));
		rsp_size = 0;
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	memcpy(new_rsp->body, &sm_rsp_body, sizeof(sm_rsp_body));
	sm_rsp = (tcm_sa_sm_rsp_body *) new_rsp->body;
	sm_rsp->opt = sm_req->opt;

out:
	*size = rsp_size;
	*rsp = new_rsp;

	sysmgr_trace_exit();
	return (ret);
}

e_ret sa_cfgmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size)
{

	e_ret ret = eRET_SUCCESS;
	int rsp_size;
	tcm_sa_rsp_body *new_rsp;
	tcm_sa_cm_req_body *cm_req;
	tcm_sa_cm_rsp_body *cm_rsp;
	tcm_sa_cm_rsp_body cm_rsp_body;

	sysmgr_trace_enter();

	rsp_size = 0;
	new_rsp = NULL;

	cm_req = (tcm_sa_cm_req_body *) req->body;
	memset(&cm_rsp_body, 0, sizeof(cm_rsp_body));

	switch (cm_req->opt) {
	case eCFG_MGR_OPT_DUMP_CFG:
		ret = pf_dep_dump_cfg(cm_rsp_body.cfg_file);
		sysmgr_dbg("pf_dep_dump_cfg() cfgfile [%s], ret: %d\n", cm_rsp_body.cfg_file, ret);
		break;

	case eCFG_MGR_OPT_LOAD_CFG:
		ret = pf_dep_load_cfg(cm_req->cfg_file);
		sysmgr_dbg("pf_dep_load_cfg() cfgfile [%s], ret: %d\n", cm_req->cfg_file, ret);
		if (ret == eRET_SUCCESS) {
			pf_dep_reboot();
		}
		break;

	case eCFG_MGR_OPT_RESET_CFG:
		ret = pf_dep_reset_cfg();
		sysmgr_dbg("pf_dep_reset_cfg() ret: %d\n", ret);
		if (ret == eRET_SUCCESS) {
			pf_dep_reboot();
		}
		break;

	default:
		ret = eRET_INVALID_ARG;
		break;
	}

	rsp_size = sizeof(*new_rsp) + sizeof(*cm_rsp);
	new_rsp = malloc(rsp_size);
	if (new_rsp == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", rsp_size, errno, strerror(errno));
		rsp_size = 0;
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	memcpy(new_rsp->body, &cm_rsp_body, sizeof(cm_rsp_body));
	cm_rsp = (tcm_sa_cm_rsp_body *) new_rsp->body;
	cm_rsp->opt = cm_req->opt;

out:
	*size = rsp_size;
	*rsp = new_rsp;

	sysmgr_trace_exit();
	return (ret);
}

e_ret sa_fwmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size)
{

	e_ret ret = eRET_SUCCESS;
	int rsp_size;
	tcm_sa_rsp_body *new_rsp;
	tcm_sa_fm_req_body *fm_req;
	tcm_sa_fm_rsp_body *fm_rsp;
	tcm_sa_fm_rsp_body fm_rsp_body;

	sysmgr_trace_enter();

	rsp_size = 0;
	new_rsp = NULL;

	fm_req = (tcm_sa_fm_req_body *) req->body;
	memset(&fm_rsp_body, 0, sizeof(fm_rsp_body));

	switch (fm_req->opt) {
	case eFW_MGR_OPT_GET_VERSION:
		strcpy(fm_rsp_body.fm_info.version, sa->fw_info.version);
		ret = eRET_SUCCESS;
		break;

	case eFW_MGR_OPT_DO_LOCAL_UPGRADE:
		ret = pf_dep_do_local_upgrade(sa, fm_req->fw_file);
		if (ret == eRET_SUCCESS) {
			pf_dep_reboot();
		}
		sysmgr_dbg("pf_dep_do_local_upgrade(%s) ,ret: %d\n", fm_req->fw_file, ret);
		break;

	case eFW_MGR_OPT_START_FOTA_CHECK:
		ret = pf_dep_start_fota_check();
		sysmgr_dbg("pf_dep_start_fota_check() ,ret: %d\n", ret);
		break;

	case eFW_MGR_OPT_QUERY_FOTA_CHECK:
		ret = pf_dep_query_fota_check();
		sysmgr_dbg("pf_dep_query_fota_check() ,ret: %d\n", ret);
		if (ret == eRET_SUCCESS) {
			ret = pf_dep_do_fota_check(sa);
			if (sa->fota_info.version[0] != 0) {
				fm_rsp_body.fm_info = sa->fota_info;
			}
			sysmgr_dbg("pf_dep_do_fota_check(%s) ,ret: %d\n", fm_rsp_body.fm_info.version, ret);
		}
		break;

	case eFW_MGR_OPT_CANCEL_FOTA_CHECK:
		ret = pf_dep_cancel_fota_check();
		sysmgr_dbg("pf_dep_query_fota_check() ,ret: %d\n", ret);
		break;

	case eFW_MGR_OPT_START_FOTA_UPGRADE:
		ret = pf_dep_start_fota_upgrade(sa);
		sysmgr_dbg("pf_dep_start_fota_upgrade() ,ret: %d\n", ret);
		break;

	case eFW_MGR_OPT_QUERY_FOTA_UPGRADE:
		ret = pf_dep_query_fota_upgrade();
		sysmgr_dbg("pf_dep_query_fota_upgrade(), ret: %d\n", ret);
		break;

	case eFW_MGR_OPT_CANCEL_FOTA_UPGRADE:
		ret = pf_dep_cancel_fota_upgrade();
		sysmgr_dbg("pf_dep_cancel_fota_upgrade(), ret: %d\n", ret);
		break;

	default:
		ret = eRET_INVALID_ARG;
		break;
	}

	rsp_size = sizeof(*new_rsp) + sizeof(*fm_rsp);
	new_rsp = malloc(rsp_size);
	if (new_rsp == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", rsp_size, errno, strerror(errno));
		rsp_size = 0;
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	memcpy(new_rsp->body, &fm_rsp_body, sizeof(fm_rsp_body));
	fm_rsp = (tcm_sa_fm_rsp_body *) new_rsp->body;
	fm_rsp->opt = fm_req->opt;

out:
	*size = rsp_size;
	*rsp = new_rsp;

	sysmgr_trace_exit();
	return (ret);
}

e_ret sa_logmgr_proc_req(tsys_admin * sa, tcm_sa_req_body * req, tcm_sa_rsp_body ** rsp, int *size)
{

	e_ret ret = eRET_SUCCESS;
	int rsp_size;
	tcm_sa_rsp_body *new_rsp;
	tcm_sa_lm_req_body *lm_req;
	tcm_sa_lm_rsp_body *lm_rsp;
	tcm_sa_lm_rsp_body lm_rsp_body;

	sysmgr_trace_enter();

	rsp_size = 0;
	new_rsp = NULL;

	lm_req = (tcm_sa_lm_req_body *) req->body;
	memset(&lm_rsp_body, 0, sizeof(lm_rsp_body));

	switch (lm_req->opt) {
	case eLOG_MGR_DUMP_LOG:
		/*
		 * TODO: dump log to file.
		 * pf_dep_dump_log().
		 */
		ret = eRET_SUCCESS;
		break;

	default:
		ret = eRET_INVALID_ARG;
		break;
	}

	rsp_size = sizeof(*new_rsp) + sizeof(*lm_rsp);
	new_rsp = malloc(rsp_size);
	if (new_rsp == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", rsp_size, errno, strerror(errno));
		rsp_size = 0;
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	memcpy(new_rsp->body, &lm_rsp_body, sizeof(lm_rsp_body));
	lm_rsp = (tcm_sa_lm_rsp_body *) new_rsp->body;
	lm_rsp->opt = lm_req->opt;

out:
	*size = rsp_size;
	*rsp = new_rsp;

	sysmgr_trace_exit();
	return (ret);
}

e_ret run_ntpclient_update_time(const char *netserver)
{
	int rc;
	tos_dep_task task;

	sysmgr_trace_enter();

	if (netserver == NULL) {
		return (eRET_FAILURE);
	}
	os_dep_killall("ntpclient", "-SIGTERM");
	usleep(1000);
	rc = os_dep_do_system_raw(eBOOL_FALSE, &task, "ntpclient", "-s", "-c", "100", "-h", netserver, "-i", "6", NULL);
	sysmgr_dbg("os_dep_do_system(ntpclient), rc: %d\n", rc);

	sysmgr_trace_exit();

	return (eRET_SUCCESS);
}
